home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
zendisk2.zip
/
LST11-24.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-02-15
|
4KB
|
118 lines
;
; *** Listing 11-24 ***
;
; Determines whether two zero-terminated strings differ, and
; if so where, using REP SCASB to find the terminating zero
; to determine one string length, and then using REPZ CMPSW
; to compare the strings.
;
jmp Skip
;
TestString1 label byte
db 'This is a test string that is '
db 'z'
db 'terminated with a zero byte...',0
TestString2 label byte
db 'This is a test string that is '
db 'a'
db 'terminated with a zero byte...',0
;
; Compares two zero-terminated strings.
;
; Input:
; DS:SI = first zero-terminated string
; ES:DI = second zero-terminated string
;
; Output:
; DS:SI = pointer to first differing location in
; first string, or 0 if the byte wasn't found
; ES:DI = pointer to first differing location in
; second string, or 0 if the byte wasn't found
;
; Registers altered: AL, CX, DX, SI, DI
;
; Direction flag cleared
;
; Note: Does not handle strings that are longer than 64K
; bytes or cross segment boundaries.
;
; Note: If there is no terminating zero in the first 64K-1
; bytes of a string, the string is treated as if byte
; 64K is a zero without checking, since if it isn't
; the string isn't zero-terminated at all.
;
CompareStrings:
mov dx,di ;set aside the start of the second
; string
sub al,al ;we'll search for zero in the second
; string to see how long it is
mov cx,0ffffh ;long enough to handle any string
; up to 64K-1 bytes in length. Any
; longer string will be treated as
; if byte 64K is zero
cld
repnz scasb ;find the terminating zero
not cx ;length of string in bytes, including
; the terminating zero except in the
; case of a string that's exactly 64K
; long including the terminating zero
mov di,dx ;get back the start of the second
; string
shr cx,1 ;get count in words
jnc CompareStringsWord
;if there's no odd byte, go directly
; to comparing a word at a time
cmpsb ;compare the odd bytes of the
; strings
jnz CompareStringsDifferentByte
;we've already found a difference
CompareStringsWord:
;there's no need to guard against
; CX=0 here, since we know that if
; CX=0 here, the preceding CMPSB
; must have successfully compared
; the terminating zero bytes of the
; strings (which are the only bytes
; of the strings), and the Zero flag
; setting of 1 from CMPSB will be
; preserved by REPZ CMPSW if CX=0,
; resulting in the correct
; conclusion that the strings are
; identical
repz cmpsw ;compare the rest of the strings a
; word at a time for speed
jnz CompareStringsDifferent ;they're not the same
sub si,si ;return 0 pointers indicating that
mov di,si ; the strings are identical
ret
CompareStringsDifferent:
;the strings are different, so we
; have to figure which byte in the
; word just compared was the first
; difference
dec si ;point back to the second byte of
dec di ; the differing word in each string
dec si ;point back to the differing byte in
dec di ; each string
lodsb
scasb ;compare that first byte again
jz CompareStringsDone
;if the first bytes are the same,
; then it must have been the second
; bytes that differed. That's where
; we're pointing, so we're done
CompareStringsDifferentByte:
dec si ;the first bytes differed, so point
dec di ; back to them
CompareStringsDone:
ret
;
Skip:
call ZTimerOn
mov si,offset TestString1 ;point to one string
mov di,seg TestString2
mov es,di
mov di,offset TestString2 ;point to other string
call CompareStrings ;and compare the strings
call ZTimerOff